<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;

/**
 * Class ModelCommand
 * @package App\Console\Commands
 */
class ModelCommand extends Command
{
    use CommandTrait;
    /**
     * @var string
     */
    protected $signature = 'create:model {--table=} {--path=}';
    /**
     * @var string
     */
    protected $basePath = 'app/Models';

    /**
     * @name: handle
     * @author: lisa
     * @datetime: 2021/8/3 10:37
     */
    public function handle()
    {
        $table          = $this->option('table');
        $basePath       = $this->option('path');
        $this->basePath = $basePath ?: $this->basePath;
        if (!$table) $this->error('请输入表名');
        if (!$this->isTableExists($table)) $this->error("该表不存在");
        $fileName  = Str::singular($table) . ".php";
        $fileName  = $this->getFileName($fileName);
        $path      = $this->getPath($fileName);
        $structure = $this->getTableStructure($table);
        list($namespace, $className) = $this->getNamespaceAndClassName($path);
        list($columns, $primaryKey, $whereSymbols, $getAttributes, $setAttributes) = $this->getTableColumnsAndPrimaryKeyAndWhereSymbols($structure);
        $this->render($path, [
            'table'         => $table,
            'namespace'     => $namespace,
            'className'     => $className,
            'columns'       => $columns,
            'whereSymbols'  => $whereSymbols,
            'primaryKey'    => $primaryKey,
            'getAttributes' => $getAttributes,
            'setAttributes' => $setAttributes
        ], $this->getRenderHtml());
    }

    /**
     * 获取表列、主键、查询条件
     * @param $tableStructure
     * @name: getTableColumnsAndPrimaryKeyAndWhereSymbols
     * @return array
     * @author: lisa
     * @datetime: 2021/8/3 11:09
     */
    public function getTableColumnsAndPrimaryKeyAndWhereSymbols($tableStructure): array
    {
        $primaryKey    = null;
        $whereSymbols  = [];
        $columns       = [];
        $getAttributes = [];
        $setAttributes = [];
        foreach ($tableStructure as $k => $v) {
            $field = Arr::get($v, 'Field');
            $type  = Arr::get($v, 'Type');
            $key   = Arr::get($v, 'Key');
            if ($this->isPrimaryKey($key)) $primaryKey = $field;
            if ($this->isNumber($type)) $whereSymbols[$field] = '=';
            else if ($this->isString($type)) $whereSymbols[$field] = 'like';
            $columns[] = $field;
            if (!in_array($field, ['created_at', 'updated_at'])) {
                if ($this->isAmount($field)) {
//                    $getAttributes[] = $this->createGetAmountAttribute($field);
//                    $setAttributes[] = $this->createSetAmountAttribute($field);
                } else if ($this->isDateTime($type)) {
                    $getAttributes[] = $this->createGetDateTimeAttribute($field);
                } else if ($this->isDate($type)) {
                    $getAttributes[] = $this->createGetDateAttribute($field);
                }
            }
        }
        $columns       = $this->createPreArrayString($columns);
        $whereSymbols  = $this->createPreArrayString($whereSymbols);
        $getAttributes = implode("\n", $getAttributes);
        $setAttributes = implode("\n", $setAttributes);
        return [$columns, $primaryKey, $whereSymbols, $getAttributes, $setAttributes];
    }

    /**
     * @param $field
     * @return string
     * @name: createGetAmountAttribute
     * @author: lisa
     * @datetime: 2021/9/6 14:35
     */
    public function createGetAmountAttribute($field)
    {
        $name = 'get_' . $field . '_attribute';
        $name = Str::camel($name);
        $str  = <<<html
    public function $name(\$value)
    {
        return MoneyHelper::f2y(\$value, false);
    }
html;
        return $str;
    }

    /**
     * @param $field
     * @return string
     * @name: createGetDateAttribute
     * @author: lisa
     * @datetime: 2021/9/6 14:35
     */
    public function createGetDateAttribute($field)
    {
        $name = 'get_' . $field . '_attribute';
        $name = Str::camel($name);
        $str  = <<<html
    public function $name(\$value)
    {
        return BaseFormat::formatDate(\$value);
    }
html;
        return $str;
    }

    /**
     * @param $field
     * @return string
     * @name: createGetDateTimeAttribute
     * @author: lisa
     * @datetime: 2021/9/6 14:35
     */
    public function createGetDateTimeAttribute($field)
    {
        $name = 'get_' . $field . '_attribute';
        $name = Str::camel($name);
        $str  = <<<html
    public function $name(\$value)
    {
        return BaseFormat::formatDateTime(\$value);
    }
html;
        return $str;
    }

    /**
     * @param $field
     * @return string
     * @name: createSetAmountAttribute
     * @author: lisa
     * @datetime: 2021/9/6 14:35
     */
    public function createSetAmountAttribute($field)
    {
        $name = 'set_' . $field . '_attribute';
        $name = Str::camel($name);
        $str  = <<<html
    public function $name(\$value)
    {
        return \$this->attributes['{$field}'] = MoneyHelper::y2f(\$value);
    }
html;
        return $str;
    }

    /**
     * @name: getRenderHtml
     * @return string
     * @author: lisa
     * @datetime: 2021/8/3 11:53
     */
    public function getRenderHtml()
    {
        return <<<html
<?php
namespace {namespace};
use Carbon\Carbon;
use App\Models\BaseModel;
use App\Helpers\MoneyHelper;
use App\Format\BaseFormat;

class {className} extends BaseModel
{
    /**
     * Define table name
     *
     * @var string
     */
    protected \$table = '{table}';

    /**
     * Define a primary key
     *
     * @var string
     */
    protected \$primaryKey = '{primaryKey}';

    /**
     * A property that cannot be batched.
     *
     * @var array
     */
    protected \$guarded = ['{primaryKey}'];
    protected \$hidden = ['updated_at'];
    /*********************************************属性格式化***************************************************************/
    {getAttributes}
    /*********************************************设置属性***************************************************************/
    {setAttributes}
    /*********************************************模型操作***************************************************************/
    public function scopeBgBaseQuery(\$query, \$whereParams = []) {
    }
    public function scopeApiBaseQuery(\$query, \$whereParams = []) {
    }
    /*********************************************模型关联***************************************************************/

}
html;
    }

}
